package org.knot.autojmx.spring;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.knot.autojmx.annotations.AutoJMX;
import org.knot.autojmx.api.AutoJMXAPI;
import org.knot.autojmx.exception.AutoJMXException;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@AutoJMX
@Component
public class ManagerSpringMBean implements ApplicationContextAware {
	
	protected final static Log logger = LogFactory.getLog(ManagerSpringMBean.class);
	
	private ApplicationContext applicationContext;
	
	/**
	 *  动态将销毁已发布的JMXBean
	 *  
	 * @param name class name
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws AutoJMXException
	 * @throws ClassNotFoundException 
	 */
	public void detoryMBeanByClassName(String className) throws InstantiationException, IllegalAccessException, AutoJMXException, ClassNotFoundException
	{
		Class clazz = this.getClass().getClassLoader().loadClass(className);
		Object bean = applicationContext.getBean(clazz);
		if (null == bean){
			new AutoJMXException("This class: "  +  className + " is not exists at applicationContext");
		}
		String[] beanNames = applicationContext.getBeanNamesForType(clazz);
		for (String name : beanNames){
			if (null != AutoJMXAPI.getBeans().get(name)){
				AutoJMXAPI.Instance().destoryJMXBean(bean, name);
				logger.info("detory MBean : " + className + " success");
				return;
			}
		}
	}

	
	/**
	 *  动态将单列类发布成JMXBean
	 * @param beanName can is empty
	 * @param name class name
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws AutoJMXException
	 */
	public void createMBeanByClassName(String className) throws ClassNotFoundException, InstantiationException, IllegalAccessException, AutoJMXException  
	{
		Class clazz = this.getClass().getClassLoader().loadClass(className);
		Object bean = applicationContext.getBean(clazz);
		if (null == bean){
			new AutoJMXException("This class: "  +  className + " is not exists at applicationContext");
		}
		AutoJMX autoJMX = ManagerSpringMBean.class.getAnnotation(AutoJMX.class);
		String[] beanNames = applicationContext.getBeanNamesForType(clazz);
		for (String name : beanNames){
			if (null == AutoJMXAPI.getBeans().get(name)){
				AutoJMXAPI.Instance().createJMXBean(bean, name, autoJMX);
				logger.info("create MBean : " + className + " success");
				break;
			}
		}
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}
}
